package com.ytjj.qmyx.admin.service.data.impl;

import com.ytjj.qmyx.admin.constants.data.MongoCollectionNameConstants;
import com.ytjj.qmyx.admin.dao.ClickConfigDao;
import com.ytjj.qmyx.admin.model.data.request.ClickStatisticsRequest;
import com.ytjj.qmyx.admin.model.data.response.ClickStatisticsResponse;
import com.ytjj.qmyx.admin.service.data.ClickStatisticsService;
import com.ytjj.qmyx.mall.model.ClickConfig;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 *
 *  *
 **/
@Service
public class ClickStatisticsServiceImpl implements ClickStatisticsService {

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private ClickConfigDao clickConfigDao;

    @Override
    public List<ClickStatisticsResponse> getClickStatisticsList(ClickStatisticsRequest request) {
        List<ClickStatisticsResponse> pageList = new ArrayList<>();

        Criteria criteria = Criteria.where("platform").is(request.getPlatform());
        if(request.getChannel() != null && request.getChannel() != "") {
            criteria.and("channel").is(request.getChannel());
        }
        if(request.getClickType() != null && request.getClickType() != "") {
            criteria.and("clickType").is(request.getClickType());
        }
        if(request.getDayTime() != null && request.getDayTime() != "") {
            criteria.and("dayTime").is(request.getDayTime());
        }
        /*Date startTime, endTime;
        LocalDate today = LocalDate.now();
        if(request.getDayType().equals("day")) {
            criteria.and("dayTime").is(CalendarUtil.dateFormat(new Date()));
        } else if(request.getDayType().equals("week")) {
            startTime = CalendarUtil.dateFormatParse(today.minusDays(6));
            endTime = CalendarUtil.getEndTime(CalendarUtil.dateFormatParse(today));
            criteria.and("createTime").gte(startTime).lte(endTime);
        } else if(request.getDayType().equals("month")) {
            startTime = CalendarUtil.dateFormatParse(today.minusDays(29));
            endTime = CalendarUtil.getEndTime(CalendarUtil.dateFormatParse(today));
            criteria.and("createTime").gte(startTime).lte(endTime);
        } else {
            throw new ApiException("请选择查看的数据类型：日/周/月");
        }*/

        // 获取整体列表数据
        List<Map> infoList = aggregateList(criteria);

        // 设值-访问人数
        List<Map> visitList = aggregateNum(criteria);

        // 设值-访问新人数
        List<Map> newVisitList = aggregateNewUser(criteria);

        // 转换点击统计中的页面名称字段
        List<ClickConfig> clickList = clickConfigDao.selList();

        if(infoList != null) {
            for(Map map : infoList) {
                ClickStatisticsResponse response = new ClickStatisticsResponse();
                response.setPlatform((String) map.get("platform"));
                response.setChannel(map.get("channel") == null ? "" : (String)map.get("channel"));
                response.setClickType(map.get("clickType") == null ? "" : (String) map.get("clickType"));
                response.setHappenNum(Integer.parseInt(map.get("happenNum").toString()));

                // 获取访问人数
                Map visitNum =  visitList.stream()
                        .filter(item -> {
                            if(item.get("clickType") != null) {
                               return item.get("clickType").equals(map.get("clickType"));
                            }
                            return false;
                        }).findAny().orElse(null);
                if(visitNum != null) {
                    response.setVisitNum(Integer.parseInt(visitNum.get("visitNum").toString()));
                }

                // 获取访问新人数
                Map visitNewNum = newVisitList.stream()
                        .filter(item -> item.get("clickType").equals(map.get("clickType")))
                        .findAny().orElse(null);
                if(visitNewNum !=null) {
                    response.setVisitNewNum(Integer.parseInt(visitNewNum.get("visitNewNum").toString()));
                }

                ClickConfig clickType = clickList.stream()
                        .filter(item -> item.getClickType().equals(map.get("clickType")))
                        .findAny().orElse(null);
                response.setPageName(clickType == null ? response.getClickType():clickType.getClickName());
                pageList.add(response);
            }
        }
        return pageList;
    }

    public List<Map> aggregateList(Criteria criteria) {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("clickType").count().as("happenNum")
                        .last("platform").as("platform")
                        .last("channel").as("channel")
                        .last("clickType").as("clickType")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.CLICK_STATISTICS, Map.class);
        return results.getMappedResults();
    }

    public List<Map> aggregateNum(Criteria criteria) {
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("clickType", "uuid"),
                Aggregation.group("clickType").count().as("visitNum").last("clickType").as("clickType")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.CLICK_STATISTICS, Map.class);
        return results.getMappedResults();
    }

    public List<Map> aggregateNewUser(Criteria criteria) {
        criteria.and("isNewUser").is(1);
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("clickType", "uuid"),
                Aggregation.group("clickType").count().as("visitNewNum").last("clickType").as("clickType")
        );
        AggregationResults<Map> results = mongoTemplate.aggregate(aggregation, MongoCollectionNameConstants.CLICK_STATISTICS, Map.class);
        return results.getMappedResults();
    }

}
